package com.railway.switchs.action.login;

import com.railway.switchs.base.BaseResponse;
import com.railway.switchs.constant.SystemConstant;
import com.railway.switchs.domain.dto.authority.AuthorityRolePermission;
import com.railway.switchs.domain.dto.log.LoginLog;
import com.railway.switchs.domain.dto.user.UserInfo;
import com.railway.switchs.domain.query.authority.AuthorityRolePermissionQuery;
import com.railway.switchs.domain.query.user.UserInfoQuery;
import com.railway.switchs.enums.EnumPermissionType;
import com.railway.switchs.enums.EnumReturnResult;
import com.railway.switchs.enums.EnumSqlOrder;
import com.railway.switchs.service.authority.IAuthorityRolePermissionService;
import com.railway.switchs.service.log.ILoginLogService;
import com.railway.switchs.service.user.IUserInfoService;
import com.railway.switchs.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @ClassName LoginAction
 * @Author 魏梓晟
 * @Version 1.0
 **/
@Controller
@Slf4j
@RequestMapping("/back/admin")
public class LoginAction {

    @Autowired
    private IUserInfoService userInfoService;

    @Autowired
    private ILoginLogService loginLogService;

    @Autowired
    private IAuthorityRolePermissionService authorityRolePermissionService;
    /**
     * 登录页面
     * @return
     */
    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String login(){
        return "login";
    }

    /**
     * 登录
     * @param loginAccount
     * @param loginPassword
     * @return
     */
    @RequestMapping(value = "/main",method = RequestMethod.POST)
    public ModelAndView index(@RequestParam("loginAccount") String loginAccount, @RequestParam("loginPassword") String loginPassword) {
        ModelAndView mav = new ModelAndView();
        try {
            String ip = IpAddressUtil.getIpAddr(ServeltUtil.getRequest());
            UserInfoQuery userInfoQuery = new UserInfoQuery();
            userInfoQuery.setNickName(loginAccount);
            List<UserInfo> userInfoList = userInfoService.getList(userInfoQuery);
            if(StringUtil.isEmpty(userInfoList)){
                log.info("查无此账号:"+loginAccount);
                mav.addObject(SystemConstant.ERROR_KEY, "输入的账号或密码错误");
                mav.setViewName("login");
                return mav;
            }
            UserInfo userInfo = userInfoList.get(0);
            if(!checkPassword(userInfo,loginPassword)){
                log.info("密码错误:"+loginAccount);
                mav.addObject(SystemConstant.ERROR_KEY, "输入的账号或密码错误");
                mav.setViewName("login");
                return mav;
            }
            //记录登录日志
            saveLoginLog(userInfo,ip);
            //更新最后上线时间
            updateOnLineTime(userInfo);
            //将userAccount存到session中
            ServeltUtil.getSession().setAttribute(SystemConstant.USERACCOUNT_KEY,userInfo.getUserAccount());
            mav.addObject("userInfo",userInfo);
            mav.setViewName("index");
        } catch (Exception e) {
            log.info("系统异常:" + loginAccount);
            mav.addObject(SystemConstant.ERROR_KEY, "系统异常");
            mav.setViewName("login");
        }
        return mav;
    }

    /**
     * 退出
     * @return
     */
    @RequestMapping(value = "/logout",method = RequestMethod.GET)
    public ModelAndView logout() {
        ModelAndView mav = new ModelAndView();
        try{
            String userAccount = UserUtil.getUserAccount();
            if(StringUtil.isEmpty(userAccount)){
                log.info("退出系统失败，原因：获取的userAccount为空");
                mav.addObject(SystemConstant.ERROR_KEY, "退出系统失败，原因：获取的userAccount为空");
                mav.setViewName("login");
                return mav;
            }
        }catch (Exception e){
            log.error("退出系统异常",e);
            mav.addObject(SystemConstant.ERROR_KEY, "退出系统失败");
        }
        mav.setViewName("login");
        return mav;
    }

    /**
     * 获取菜单
     * @param query
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getMenus",method = RequestMethod.POST)
    public AuthorityRolePermissionQuery getMenus(AuthorityRolePermissionQuery query){
        try{
            List<AuthorityRolePermission> menuGroups = new ArrayList<>();
            query.setOrderField("orderNum");
            query.setOrderType(EnumSqlOrder.ASC_ORDER.getCode());
            query.setPermissionType(EnumPermissionType.MENU_GUOP.getCode());
            menuGroups = authorityRolePermissionService.getList(query);
            if(StringUtil.isNotEmpty(menuGroups)){
                for(AuthorityRolePermission authorityRolePermission : menuGroups){
                    query.setPermissionType(EnumPermissionType.MENU.getCode());
                    query.setParentCode(authorityRolePermission.getPermissionCode());
                    List<AuthorityRolePermission> menus = authorityRolePermissionService.getList(query);
                    authorityRolePermission.setChildrenData(menus);
                }
            }
            query.setData(menuGroups);
            query.setCount(menuGroups.size());
            query.setCode(EnumReturnResult.RETURN_200.getCode());
        }catch (Exception e){
            log.error("获取菜单数据异常",e);
            query.setCode(EnumReturnResult.RETURN_404.getCode());
            query.setMsg("获取数据异常");
        }
        return query;
    }

    /**
     * 进入修改密码页面
     * @return
     */
    @RequestMapping(value = "/editpassword",method = RequestMethod.GET)
    public ModelAndView preEditPassword(){
        ModelAndView mav = new ModelAndView();
        mav.addObject("userAccount",UserUtil.getUserAccount());
        mav.setViewName("admin/editpassword");
        return mav;
    }

    /**
     * 修改密码
     * @param userAccount
     * @param oldPassword
     * @param newPaword
     * @param confirmPassword
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/editpassword",method = RequestMethod.POST)
    public BaseResponse editPassword(String userAccount,String oldPassword, String newPaword, String confirmPassword){
        BaseResponse response = new BaseResponse();
        try{
            if(!newPaword.equals(confirmPassword)){
                response.setMsg("两次输入的密码不一致");
                response.setCode(EnumReturnResult.RETURN_404.getCode());
                return response;
            }
            UserInfoQuery userInfoQuery = new UserInfoQuery();
            userInfoQuery.setUserAccount(userAccount);
            List<UserInfo> userInfoList = userInfoService.getList(userInfoQuery);
            if(StringUtil.isNotEmpty(userInfoList)){
                UserInfo userInfo = userInfoList.get(0);
                if(!checkPassword(userInfo,oldPassword)){
                    response.setMsg("旧密码输入错误");
                    response.setCode(EnumReturnResult.RETURN_404.getCode());
                    return response;
                }
                String randomPassword = "123456";
                log.info(userAccount + "随机生成的密码为:" + randomPassword);
                Map<String,String> passMap = Md5Util.encryption(randomPassword);
                if(StringUtil.isNotNull(passMap)){
                    userInfo.setUserPassword(passMap.get("md5"));
                    userInfo.setSalt(passMap.get("salt"));
                }
                userInfoService.edit(userInfo);
                response.setMsg("修改密码成功");
                response.setCode(EnumReturnResult.RETURN_200.getCode());
                return response;
            }
            response.setMsg("修改密码错误");
            response.setCode(EnumReturnResult.RETURN_404.getCode());
        }catch (Exception e){
            response.setMsg("修改密码异常");
            response.setCode(EnumReturnResult.RETURN_404.getCode());
        }
        return response;
    }

    /**
     * 更新最后上线时间
     * @param userInfo
     */
    private void updateOnLineTime(UserInfo userInfo) {
        userInfo.setOnlineTime(new Date());
        userInfoService.edit(userInfo);
    }

    /**
     * 校验密码是否正确
     * @param userInfo
     * @param loginPassword
     * @return
     */
    private boolean checkPassword(UserInfo userInfo,String loginPassword){
        if(StringUtil.isNotNull(userInfo)){
            return Md5Util.verify(loginPassword,userInfo.getSalt(),userInfo.getUserPassword());
        }
        log.info("非权限用户:"+userInfo.getNickName());
        return false;
    }

    /**
     * 保存登录日志
     * @param userInfo
     * @param ip
     * @return
     */
    private void saveLoginLog(UserInfo userInfo,String ip) {
        LoginLog loginLog = new LoginLog();
        loginLog.setUserAccount(userInfo.getUserAccount());
        loginLog.setNickName(userInfo.getNickName());
        loginLog.setUserName(userInfo.getUserName());
        loginLog.setLoginIp(IpAddressUtil.getIpAddr(ServeltUtil.getRequest()));
        loginLog.setUserType(userInfo.getRoleCode());
        loginLog.setLoginIp(ip);
        loginLog.setLoginAddress(IpAddressUtil.getAddressByIp(ip));
        loginLogService.add(loginLog);
    }

}
